package com.abl.core.common.util;

import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class StringKit {
    /**
     * 字符串替换填充
     *
     * @param string 字符串，识别 {} 进行填充
     * @param objs   填充内容数组
     * @return 返回替换并填充后的新字符串
     */
    public static String format(String string, Object... objs) {
        return format(0, string, objs);
    }

    public static void formatPrint(String string, Object... objs) {
        System.out.println(format(0, string, objs));
    }

    public static String subBefore(String finStr, String content) {
        if (isBlank(content) || isBlank(finStr) || !content.contains(finStr)) {
            return null;
        }
        int index = content.indexOf(finStr);
        //        System.out.println(content);
        //        System.out.println(index);
        //        System.out.println(content.substring(0, index));
        return content.substring(0, index);
    }

    public static String subAfter(String finStr, String content) {
        if (isBlank(content) || isBlank(finStr) || !content.contains(finStr)) {
            return null;
        }
        int index = content.indexOf(finStr);
        //        System.out.println(content);
        //        System.out.println(index);
        //        System.out.println(content.substring(index + finStr.length()));
        return content.substring(index + finStr.length());
    }

    //copy to org.apache.commons
    public static boolean isBlank(CharSequence cs) {
        int strLen = length(cs);
        if (strLen != 0) {
            for (int i = 0; i < strLen; ++i) {
                if (!Character.isWhitespace(cs.charAt(i))) {
                    return false;
                }
            }

        }
        return true;
    }

    //copy to org.apache.commons
    public static int length(CharSequence cs) {
        return cs == null ? 0 : cs.length();
    }

    //copy to org.apache.commons
    public static boolean isNotBlank(CharSequence cs) {
        return !isBlank(cs);
    }

//    public static void main(String[] args) {
//        String join1 = StringKit.join(Arrays.asList("1", "10", "20", ""), ",");
//        String join2 = StringKit.join(Arrays.asList("", "1", "10", "20", ""), ",");
//        System.out.println(join1);
//        System.out.println(join2);
//    }

    //copy to org.apache.commons
    public static String join(Iterable<?> iterable, String separator) {
        return iterable == null ? null : join(iterable.iterator(), separator);
//        if (s != null) {
//            int i1 = s.indexOf(",", 0);
//            if (i1 != -1) {
//                s = s.substring(1);
//            }
//        }
//        return s;
    }

    //copy to org.apache.commons
    public static String join(Iterator<?> iterator, String separator) {
        if (iterator == null) {
            return null;
        } else if (!iterator.hasNext()) {
            return "";
        } else {
            Object first = iterator.next();
            if (!iterator.hasNext()) {
                return Objects.toString(first, "");
            } else {
                StringBuilder buf = new StringBuilder(256);
                if (first != null) {
                    buf.append(first);
                }

                while (iterator.hasNext()) {
                    if (separator != null) {
                        buf.append(separator);
                    }

                    Object obj = iterator.next();
                    if (obj != null) {
                        buf.append(obj);
                    }
                }

                return buf.toString();
            }
        }
    }

    public static boolean isNull(Object object) {
        return object == null;
    }

    /**
     * 字符串替换填充
     *
     * @param capacity 初始扩容大小（可选配置）
     * @param string   字符串，识别 {} 进行填充
     * @param objs     填充内容数组
     * @return 返回替换并填充后的新字符串
     */
    private static String format(int capacity, String string, Object... objs) {
        String replace = string.replace("{}", "#X#9527#X#");
        String[] split = replace.split("#X#9527#X#");

        StringBuilder stringBuilder = new StringBuilder();

        if (capacity == 0) {
            new StringBuilder((int) (replace.length() * 1.5));
        } else {
            new StringBuilder(capacity);
        }

        for (int i = 0; i < split.length; i++) {
            stringBuilder.append(split[i]);
            if (objs != null && objs.length > i) {
                if (objs[i] != null) {
                    stringBuilder.append(objs[i]);
                } else {
                    stringBuilder.append("NULL");
                }
            }
        }
        return stringBuilder.toString();
    }

    /**
     * 分隔字符串，返回数组
     * 默认逗号分隔
     * 默认排除空字符串，并且去重
     */
    public static ArrayList<String> split(String content) {
        return split(content, ",", true, true);
    }

    /**
     * 分隔字符串，返回数组
     * 默认排除空字符串，并且去重
     */
    public static ArrayList<String> split(String content, String splitStr) {
        return split(content, splitStr, true, true);
    }

    /**
     * 分隔字符串，返回数组
     * 排除空字符串
     */
    public static ArrayList<String> split(String content, String splitStr, boolean excludeBlank) {
        return split(content, splitStr, excludeBlank, false);
    }

    /**
     * 分隔字符串，返回数组
     * 条件判断：是否排除空字符串  是否去重
     */
    public static ArrayList<String> split(String content, String splitStr, boolean excludeBlank,
                                          boolean excludeRepeat) {
        if (isBlank(content)) return new ArrayList<>();
        if (isBlank(splitStr)) {
            ArrayList<String> list = new ArrayList<>();
            list.add(content);
            return list;
        }
        String[] split = content.split(splitStr);
        ArrayList<String> list = new ArrayList<>();

        //先排除符号
        if (excludeBlank) {
            for (String value : split) {
                if (!splitStr.equals(value)) {
                    list.add(value);
                }
            }
        }

        ArrayList<String> returnList = new ArrayList<>(list.size());
        //排除空值
        if (excludeBlank) {
            for (String value : split) {
                if (isNotBlank(value)) {
                    returnList.add(value);
                }
            }
        }
        //去重
        if (excludeRepeat) {
            returnList = new ArrayList<>(new HashSet<>(returnList));
        }

        return returnList;
    }

    public static Map<String, String> getURIParam(String uri) {
        return getURI_URL_Param("1", uri);
    }

    public static Map<String, String> getURLParam(String url) {
        return getURI_URL_Param("2", url);
    }

    private static Map<String, String> getURI_URL_Param(String type, String uri) {
        if (isBlank(uri)) return null;
        String query = "";

        if ("1".equals(type)) {
            URI obj;
            try {
                obj = new URI(uri);
                query = obj.getQuery();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        if ("2".equals(type)) {
            URL obj;
            try {
                obj = new URL(uri);
                query = obj.getQuery();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        Map<String, String> params = new HashMap<>();
        String[] pairs = query.split("&");
        for (String pair : pairs) {
            int idx = pair.indexOf("=");
            String key;
            String value;
            try {
                key = URLDecoder.decode(pair.substring(0, idx), "UTF-8");
                value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            params.put(key, value);
        }
        return params;
    }

    //生成随机位数字符串
    public static String createRandom(int length) {
        return createRandom(length, false);
    }

    //生成随机位数字符串
    public static String createRandom(int length, boolean dontZeroStart) {
        return createRandom(length, dontZeroStart, new ArrayList<>());
    }

    //生成随机位数字符串
    public static String createRandom(int length, boolean dontZeroStart, List<String> notInList) {
        StringBuilder randomStr = new StringBuilder(length);
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            int randomNumber = random.nextInt(10);
            if (i == 0 && dontZeroStart && randomNumber == 0) {
                i--;
            } else {
                randomStr.append(randomNumber);
            }
        }
        if (notInList.contains(randomStr.toString())) {
            return createRandom(length, dontZeroStart, notInList);
        } else {
            return randomStr.toString();
        }
    }

    public static CharSequence md5(String number) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
            return null;
        }
        byte[] resultByte = messageDigest.digest(number.getBytes());
        StringBuilder result = new StringBuilder();
        for (byte b : resultByte) {
            int v = 0xFF & b;
            if (v < 16) {
                result.append("0");
            }
            result.append(Integer.toHexString(v));
        }
        return result.toString();
    }
}
